using Infrastructure.Attribute;
using Infrastructure.Extensions;
using ZR.Model.FacManage.Dto;
using ZR.Model.FacManage;
using ZR.Service.FacManage.IFacManageService;
using Infrastructure;

namespace ZR.Service.FacManage
{
    /// <summary>
    /// 库位信息Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(IFacLocService), ServiceLifetime = LifeTime.Transient)]
    public class FacLocService : BaseService<FacLoc>, IFacLocService
    {
        /// <summary>
        /// 查询库位信息列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<FacLocDto> GetPageList(FacLocQueryDto parm)
        {
            var predicate = QueryExp(parm);
            var response = new PagedInfo<FacLocDto>();
            var total = 0;
            response.PageSize = parm.PageSize;
            response.PageIndex = parm.PageNum;
            response.Result = Queryable().Where(predicate.ToExpression())
                .LeftJoin<FacWhse>((loc, whse) => loc.WhseId == whse.WhseId)
                .OrderByPropertyNameIF(parm.Sort.IsNotEmpty(), parm.Sort, parm.SortType.Contains("desc") ? OrderByType.Desc : OrderByType.Asc)
                .Select((loc, whse) => new FacLocDto
                {
                    LocId = loc.LocId,
                    LocCode = loc.LocCode,
                    LocName = loc.LocName,
                    AllocCode = loc.AllocCode,
                    LocCategory = loc.LocCategory,
                    LocType = loc.LocType,
                    PutawayCode = loc.PutawayCode,
                    HasTray = loc.HasTray,
                    IsEmpty = loc.IsEmpty,
                    LocStatus = loc.LocStatus,
                    Popular = loc.Popular,
                    X = loc.X,
                    Y = loc.Y,
                    Z = loc.Z,
                    AgvAddress = loc.AgvAddress,
                    PlanCode = loc.PlanCode,
                    PackageCode = loc.PackageCode,
                    Remark = loc.Remark,
                    CreateBy = loc.CreateBy,
                    CreateTime = loc.CreateTime,
                    UpdateBy = loc.UpdateBy,
                    UpdateTime = loc.UpdateTime,
                    WhseId = loc.WhseId,
                    WhseInfo = whse.WhseCode + "  " + whse.WhseName,
                }).ToPageList(parm.PageNum, parm.PageSize, ref total);
            response.TotalNum = total;
            return response;
        }

        /// <summary>
        /// 获取货位树信息
        /// </summary>
        /// <param name="disabledWhse">禁用库区选择</param>
        /// <returns></returns>
        public List<TreeSelectInfo> GetTreeList(bool disabledWhse)
        {
            List<TreeSelectInfo> trees = new List<TreeSelectInfo>();
            //获取库区信息
            List<FacWhse> whseList = this.Context.Queryable<FacWhse>().ToList();
            //获取库位信息
            List<FacLoc> locList = this.Context.Queryable<FacLoc>().ToList();
            foreach (FacWhse whse in whseList)
            {
                TreeSelectInfo tree = new TreeSelectInfo();
                tree.value = whse.WhseId;
                tree.label = whse.WhseCode + " " + whse.WhseName;
                tree.disabled = disabledWhse;
                foreach (FacLoc loc in locList.Where(it => it.WhseId == whse.WhseId).ToList())
                {
                    tree.children.Add(new TreeSelectInfo()
                    {
                        value = loc.LocId,
                        label = loc.LocCode
                    });
                }
                trees.Add(tree);
            }
            return trees;
        }

        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="LocId"></param>
        /// <returns></returns>
        public FacLoc GetInfo(string LocId)
        {
            var response = Queryable()
                .Where(x => x.LocId == LocId)
                .First();

            return response;
        }

        /// <summary>
        /// 添加库位信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public FacLoc AddFacLoc(FacLoc model)
        {
            if (this.Any(it => it.LocCode == model.LocCode))
            {
                throw new CustomException($"系统中已包含{model.LocCode}编码信息");
            }
            return Insertable(model).ExecuteReturnEntity();
        }

        /// <summary>
        /// 修改库位信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateFacLoc(FacLoc model)
        {
            if (this.Any(it => it.LocCode == model.LocCode && it.LocId != model.LocId))
            {
                throw new CustomException($"系统中已包含{model.LocCode}编码信息");
            }
            return Update(model, true);
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<FacLoc> QueryExp(FacLocQueryDto parm)
        {
            var predicate = Expressionable.Create<FacLoc>();

            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.WhseId), it => it.WhseId == parm.WhseId);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LocCode), it => it.LocCode == parm.LocCode);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LocName), it => it.LocName.Contains(parm.LocName));
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LocType), it => it.LocType == parm.LocType);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LocCategory), it => it.LocCategory == parm.LocCategory);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LocStatus), it => it.LocStatus == parm.LocStatus);
            return predicate;
        }
    }
}